package project_model;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyTest {

    private interface Thread {
        void run();
    }

    private static class RunThread implements Thread {
        public RunThread() {
        }

        @Override
        public void run() {
            System.out.println("开始运行……");
        }
    }

    // 静态代理
    private static class StaticProxy implements Thread {
        private RunThread runThread;
        @Override
        public void run() {
            if(runThread == null) {
                runThread = new RunThread();
            }
            preRun();
            runThread.run();
            postRun();
        }

        public void preRun() {
            System.out.println("运行前预处理……");
        }

        public void postRun() {
            System.out.println("运行后后续处理……");
        }
    }

    // JDK动态代理
    private static class JDKProxy implements InvocationHandler {
        private Object object;

        public JDKProxy(Object object) {
            this.object = object;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            preRun();
            Object obj = method.invoke(object, args);
            postRun();
            return obj;
        }

        public void preRun() {
            System.out.println("JDK代理前处理……");
        }

        public void postRun() {
            System.out.println("JDK代理后处理……");
        }
    }

    // cglib动态代理
    private static class CglibProxy implements MethodInterceptor {
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            preRun();
            Object obj = methodProxy.invokeSuper(o, objects);
            postRun();
            return obj;
        }

        public void preRun() {
            System.out.println("Cglib代理前处理……");
        }

        public void postRun() {

            System.out.println("Cglib代理后处理……");
        }
    }

    public static void main(String[] args) {
        StaticProxy proxy = new StaticProxy();
        proxy.run();

//        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        RunThread runThread = new RunThread();
        InvocationHandler jdkProxy = new JDKProxy(runThread);
        Thread r = (Thread) Proxy.newProxyInstance(RunThread.class.getClassLoader(), RunThread.class.getInterfaces(), jdkProxy);
        r.run();
        System.out.println(r.getClass());

//        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\IDEAProject\\j2sehexin\\project_model");
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(RunThread.class);
        enhancer.setCallback(new CglibProxy());
        RunThread thread = (RunThread) enhancer.create();
        thread.run();
    }
}
